package wzq.cn.wuziqi.core;

import wzq.cn.wuziqi.RC;
import wzq.cn.wuziqi.model.ChessBoard;
import wzq.cn.wuziqi.model.PointU;
import wzq.cn.wuziqi.model.SuccessResult;
import wzq.cn.wuziqi.utils.LogUtils;

/**
 * Created by xiawei on 15/10/23.
 */
public class VerifySuccess {

    private boolean isDebug = true;
    /**
     * 棋盘桌面上的数据
     */
    private PointU[][] pointUs ;
    /**
     * 递归深度，代表连子的数目
     */
    private int deep=0;
    /**
     * 获取胜利的结果值
     */
    private SuccessResult rs = new SuccessResult();

    /**
     * 是否是胜利了
     */
    private boolean isSuccess = false;

    /**
     * 检测是否有number 数量的链子
     * @param points
     * @param number 数量 五子棋 为5
     * @return 成功的值
     */
    public  SuccessResult verify(PointU[][] points,int number){

        if(points==null || points.length==0)return null;
        long startTime = System.currentTimeMillis();
        this.pointUs = points;
        int sizeRow = points.length;
        int sizeClo = points[0].length;
        int sizeDirect = RC.directs.length;
        for (int i = 0; ((i <sizeRow)&&!isSuccess); i++) {
            for(int k = 0; ((k < sizeClo)&&!isSuccess); k++) {
                for (int m=0;((m < sizeDirect)&&!isSuccess);m++) {
                    startVerify(number, sizeRow, RC.directs[m], sizeClo, i, k);
                }
            }
        }

        if(isDebug){
            long endTime = System.currentTimeMillis();
            LogUtils.d("verify [ s="+startTime +",e="+endTime+",diff="+(endTime-startTime)+" ]");
        }


        return  rs;
    }

    /**开始比较一个方向
     *
     * @param number
     * @param sizeRow
     * @param d
     * @param sizeClo
     * @param i
     * @param k
     */
    private void startVerify(int number, int sizeRow,ChessBoard.DIRECT d, int sizeClo, int i, int k) {
        if(!isSuccess) {
            deep = 0;
            deep = verifyDirect(i, k, number, d, sizeRow, sizeClo);
            if (isDebug) {
                if (deep > 1)
                    LogUtils.d("deep=" + deep + "DIRECT=" + d + "i=" + i + ",k=" + k);
            }
            if (deep >= number) {
                isSuccess = true;
                LogUtils.e("TAG", "胜利的结果" + rs.getRs().toString());
            }
        }
    }

    /**
     * 是否已经有对战玩家
     * @param side1
     * @param side2
     * @return
     */
    private boolean isBelong(ChessBoard.SIDE side1,ChessBoard.SIDE side2){
        if(side1==side2 && side1!= ChessBoard.SIDE.NONE){
            return true;
        }
        return false;
    }

    private int verifyDirect(int x,int y, int number,ChessBoard.DIRECT d,int sizeRow,int sizeClo) {
        deep ++;

        PointU psrc = pointUs[x][y];

        if(d== ChessBoard.DIRECT.BUTTOM){
            // Y+1
            int nextX  = x;
            int nexty = y+1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty)) {
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            }else{
                //下一个 不能继续了
                verfyStop();
            }
        }else if(d== ChessBoard.DIRECT.BUTTON_LEFT){
            // x+1 y+1

            int nextX  = x-1;
            int nexty = y+1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty)) {
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            }else{
                //下一个 不能继续了
                verfyStop();
            }
        }else if(d == ChessBoard.DIRECT.LEFT){

            int nextX  = x-1;
            int nexty = y;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }else if(d== ChessBoard.DIRECT.LEFT_TOP){

            int nextX  = x-1;
            int nexty = y-1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }else if(d == ChessBoard.DIRECT.RIGHT){
            int nextX  = x+1;
            int nexty = y;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }else  if(d== ChessBoard.DIRECT.RIGHT_BUTTON){
            int nextX  = x+1;
            int nexty = y+1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }else if(d == ChessBoard.DIRECT.TOP){
            int nextX  = x;
            int nexty = y-1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }else if(d == ChessBoard.DIRECT.TOP_RIGHT){
            // x+1 y-1
            int nextX  = x+1;
            int nexty = y-1;

            if (verfyNext(sizeRow, sizeClo, psrc, nextX, nexty))
                return verifyDirect(nextX, nexty, number, d, sizeRow, sizeClo);
            else{
                //下一个 不能继续了
                verfyStop();
            }

        }
        return deep;
    }



    private void verfyStop() {
        if(!isSuccess) {
            rs.getRs().clear();
        }
    }

    /**
     *  是否需要比较下一个
     * @param sizeRow
     * @param sizeClo
     * @param psrc
     * @param nextX
     * @param nexty
     * @return
     */
    private boolean verfyNext(int sizeRow, int sizeClo, PointU psrc, int nextX, int nexty) {
        if((nextX<sizeRow) && (nexty<sizeClo) && (nextX>=0) && (nexty >=0)){
            PointU pnext = pointUs[nextX][nexty];
            if(isBelong(psrc.belong,pnext.belong)){
                if(!rs.getRs().contains(psrc)){
                    rs.getRs().addFirst(psrc);
                }
                if(!rs.getRs().contains(pnext)){
                    rs.getRs().add(pnext);
                }
                return true;
            }
        }
        return false;
    }

    public PointU[][] getPointUs() {
        return pointUs;
    }

    public void setPointUs(PointU[][] pointUs) {
        this.pointUs = pointUs;
    }

    public int getDeep() {
        return deep;
    }

    public void setDeep(int deep) {
        this.deep = deep;
    }

    public SuccessResult getRs() {
        return rs;
    }

    public void setRs(SuccessResult rs) {
        this.rs = rs;
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public void setIsSuccess(boolean isSuccess) {
        this.isSuccess = isSuccess;
    }
}
